#include "../src/model.cc"

#include <cassert>
#include <cstdlib>
#include <iostream>
#include <unistd.h>

namespace
{
  using namespace playerpiano;
  using std::cerr;
  using std::endl;

  std::string
  random_string (size_t max_len)
    {
      size_t len = max_len * drand48 ();
      std::string rv (len, 0);

      for (unsigned int i = 0; i < len; ++i)
        {
          rv[i] = 'a' + ('z' - 'a') * drand48 ();
        }

      return rv;
    }

  void
  test_ensure_once ()
    {
      std::string pathname = "tmp" + random_string (16);

      Model model (Model::Open (pathname).read_only (false));
      unlink (pathname.c_str ());

      std::string name1 = random_string (16);
      std::string name2 = random_string (16);
      while (name1 == name2)
        {
          name2 = random_string (16);
        }

      std::string name3 = random_string (16);
      while (name1 == name3 ||
             name2 == name3)
        {
          name3 = random_string (16);
        }

      uint64_t length1 = lrand48 () % 40960;
      uint64_t length2 = lrand48 () % 40960;
      uint64_t length3 = lrand48 () % 40960;

      model.ensure (name1, length1)
           .ensure (name2, length2)
           .ensure (name3, length3);

      std::pair<void*, uint64_t> r1 = model.lookup (name1);
      assert ((r1.first && r1.second == length1) || 
              (cerr << "r1.first = " << r1.first << " r1.second = " << r1.second 
                    << " length1 = " << length1 << endl,
               0));

      std::pair<void*, uint64_t> r2 = model.lookup (name2);
      assert ((r2.first && r2.second == length2) || 
              (cerr << "r2.first = " << r2.first << " r2.second = " << r2.second 
                    << " length2 = " << length2 << endl,
               0));

      std::pair<void*, uint64_t> r3 = model.lookup (name3);
      assert ((r3.first && r3.second == length3) || 
              (cerr << "r3.first = " << r3.first << " r3.second = " << r3.second 
                    << " length3 = " << length3 << endl,
               0));
    }

  void
  test_ensure ()
    {
      for (unsigned int i = 0; i < 1000; ++i)
        {
          test_ensure_once ();
        }
    }
}

int
main ()
{
  srand48 (69);
  test_ensure ();
}
